#include "LoadingPro.h"
#include "../utils/Utils.h"
#include "../DevMacros.h"

LoadingPro loadingPro;

LoadingPro* LoadingPro::shareLoadingPro(){
    return &loadingPro;
}


LoadingPro::LoadingPro():
nFrameStartTime(0){
    clear();
}

void LoadingPro::addCachePlist(string plist){
    if(plist==""){
        return;
    }
    bool has=false;
    for(uint32 i=0;i<plistCache.size();i++){
        if(plistCache[i]==plist){
            has=true;
        }
    }
    if(!has){
        plistCache.push_back(plist);
    }
}



void LoadingPro::removeHasLoadPlist(string plist){
    list<string>::iterator it=plistLoaded.begin();
    
    for(;it!=plistLoaded.end();it++){
        if(*it==plist){
            plistLoaded.erase(it);
            CCSpriteFrameCache::sharedSpriteFrameCache()->removeSpriteFramesFromFile(plist.c_str());
            return;
        }
    }
}

bool LoadingPro::isHasLoadPlist(string plist){
    list<string>::iterator it=plistLoaded.begin();
    
    for(;it!=plistLoaded.end();it++){
        if(*it==plist){
            return true;
        }
    }
    return  false;
}

void LoadingPro::addTryPlist(string plist){
    if(plist==""){
        return;
    }
    
    if(!isHasLoadPlist(plist)){
        plistLoaded.push_back(plist);
        tryPistCache.push_back(plist);
    }
    
}


void LoadingPro::removeCachePlist(){
    for(uint32 i=0;i<plistCache.size();i++){
        
        CCSpriteFrameCache::sharedSpriteFrameCache()->removeSpriteFramesFromFile(plistCache[i].c_str());
        
    }
    m_pFileNames.clear();
    plistCache.clear();
    plistLoaded.clear();
    tryPistCache.clear();
}


LoadingPro::~LoadingPro(){
    
}

void LoadingPro::clearTarget(){
    
    gItemTarget.clear();
    gItemSelector.clear();
    gAllTarget.clear();
    gAllSelector.clear();
}
void LoadingPro::clear(){
    gItems.clear();
    gItemTarget.clear();
    gItemSelector.clear();
    gAllTarget.clear();
    gAllSelector.clear();
    m_nLoadedTotalCount=0;
}


string LoadingPro::getImgPath(const string &path){
	string temp=CCFileUtils::sharedFileUtils()->fullPathForFilename(path.c_str());
    const char *pszPath = temp.c_str();
    CCDictionary *dict = CCDictionary::createWithContentsOfFileThreadSafe(pszPath);
    
    
	int nLen = strlen(pszPath) - 1;
	while(*(pszPath+nLen) != '/') nLen--;
    
	string texturePath("");
    
	CCDictionary* metadataDict = (CCDictionary*)dict->objectForKey("metadata");
	if (metadataDict)
	{
		texturePath = metadataDict->valueForKey("textureFileName")->getCString();
	}
    
	if (! texturePath.empty())
	{
		string str = "";
		if(nLen > 0)
			str.append(pszPath, nLen+1);
		else
			str.append(pszPath);
        
		texturePath = str + texturePath;
	}
	else
	{
		texturePath = pszPath;
		size_t startPos = texturePath.find_last_of(".");
		texturePath = texturePath.erase(startPos);
		texturePath = texturePath.append(".png");
        
	}
    
    
    return texturePath;
    
}

void LoadingPro::addItem(const string& files,bool before){
    if(m_pFileNames.find(files)==m_pFileNames.end()){
        
        CLoadingItem* item=new CLoadingItem();
        item->cFilePath=files;
        item->cPngPath=files;
        
        string::size_type pos= item->cPngPath.find(".plist");
        
        if(pos!=item->cPngPath.npos){
            item->bIsPlist=true;
            size_t startPos = item->cPngPath.find_last_of(".");
            item->cPngPath = item->cPngPath.erase(startPos);
            item->cPngPath =getImgPath( item->cFilePath);
        }else{
            item->bIsPlist=false;
        }
        
        
        gItems.push_back(item);
        m_pFileNames[files]=item;
    }
}



void LoadingPro::addItemLoadTarget(CCObject* target, SEL_CallFuncO selector){
    if(target && selector){
        
        gItemTarget.push_back(target);
        gItemSelector.push_back(selector);
        
    }
}

void LoadingPro::addAllLoadTarget(CCObject* target, SEL_CallFunc selector){
    if(target && selector){
        gAllTarget.push_back(target);
        gAllSelector.push_back(selector);
    }
}

void LoadingPro::load(){
    m_nLoadedIndex=0;
    m_nLoadedTotalCount=gItems.size();
}



void LoadingPro::updateGame(float dt){
    
    
    
    while(gItems.size()!=0){
        if(getTimer()-nFrameStartTime>dt){
            return;
        }
        CLoadingItem* item= gItems.front();
        gItems.pop_front();
        std::string strPath = parseFilePath(item->cPngPath.c_str());
        CCTextureCache::sharedTextureCache()->addImage(strPath.c_str());
        onLoaded(item);
        SAFE_DEL(item);
    }
    
    
    
    while(tryPistCache.size()!=0){
        if(getTimer()-nFrameStartTime>dt){
            return;
        }
        string path= tryPistCache.front();
        tryPistCache.pop_front();
        addCachePlist(path);
        CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(path.c_str());
    }
    
}



int LoadingPro::getTotalCount(){
    return m_nLoadedTotalCount;
}

int LoadingPro::getLoadedCount(){
    return m_nLoadedIndex;
}



void LoadingPro::onLoaded(CLoadingItem* pParam){
    
    CCObject* target=NULL;
    SEL_CallFuncO selector=NULL;
    SEL_CallFunc allSelector=NULL;
    
    for(uint32 i=0;i<gItemTarget.size();i++){
        target=gItemTarget[i];
        selector=gItemSelector[i];
        (target->*selector)(NULL);
    }
    
    if(m_nLoadedTotalCount!=0){
        m_nLoadedIndex++;
        if(m_nLoadedIndex>=m_nLoadedTotalCount)
        {
            
            for(uint32 i=0;i<gAllTarget.size();i++){
                target=gAllTarget[i];
                allSelector=gAllSelector[i];
                (target->*allSelector)();
            }
            m_nLoadedTotalCount=0;
            
            return;
        }
        
    }
    
}